package com.mingqijia.gassafety.shared.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName DateFormatUtil.java
 * @Description 校验工具
 * @createTime 2023年01月03日 14:29:00
 */
@Slf4j
public class DateFormatUtil {


    public static final String HHmm = "HH:mm";
    public static final String YYMMDDHHmmss = "yyyy-MM-dd HH:mm:ss";


    /**
     * 日期格式判断
     */
    public static boolean checkDate(String beginDate, String endDate, String format) {
        boolean result = true;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            if (beginDate != null) {
                simpleDateFormat.parse(beginDate);
            }
            if (endDate != null) {
                simpleDateFormat.parse(endDate);
            }
        } catch (ParseException e) {
            return false;
        }
        return result;
    }


    /**
     * format 日期
     */
    public static Integer formatDate(Date currentDate, String yymmdd) {
        Integer parse = 0;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yymmdd);
            parse = Integer.parseInt(simpleDateFormat.format(currentDate));
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return parse;
    }
    /**
     * format 日期
     */
    public static String formatDateToString(Date currentDate, String yymmdd) {
        String parse = "";
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yymmdd);
            parse = simpleDateFormat.format(currentDate);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * 字符串数字校验
     */
    public static boolean checkString(String str) {
        boolean result = true;
        try {
            Integer.parseInt(str);
        } catch (NumberFormatException e) {
            result = false;
        }
        return result;
    }

    /**
     * 获取两个时间中的每一天
     *
     * @param bigtimeStr 开始时间 yyyy-MM-dd
     * @param endTimeStr 结束时间 yyyy-MM-dd
     * @return
     * @throws ParseException
     */
    public static List<String> getDays(String bigtimeStr, String endTimeStr, String format, int cycleTime, List<Integer> dateOffs) {
        if (cycleTime == 0 || dateOffs == null || !checkDate(bigtimeStr, endTimeStr, format)) {
            return new ArrayList<>();
        }
        List<Integer> indexs = new ArrayList<>();
        List<String> datas = new LinkedList<>();
        try {
            Date bigtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(bigtimeStr + " 00:00:00");
            Date endtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr + " 00:00:00");
            //定义一个接受时间的集合
            List<Date> lDate = new ArrayList<>();
            lDate.add(bigtime);
            Calendar calBegin = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calBegin.setTime(bigtime);
            Calendar calEnd = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calEnd.setTime(endtime);
            // 测试此日期是否在指定日期之后
            while (endtime.after(calBegin.getTime())) {
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                lDate.add(calBegin.getTime());
            }

            for (Date date : lDate) {
                datas.add(new SimpleDateFormat(format).format(date));
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //n*7+2
        dateOffs.sort((o1, o2) -> o2 - o1);
        for (Integer dateOff : dateOffs) {
            removeDate(cycleTime, dateOffs, datas, dateOff, indexs);
        }

        indexs.sort((o1, o2) -> o2 - o1);
        log.info("删除日期列表:{}", JSONObject.toJSON(indexs));
        for (int i : indexs) {
            if (i<=datas.size()-1){
                datas.remove(i);
            }
        }
        return datas;
    }

    /**
     * 删除日期
     *
     * @param cycleTime
     * @param dateOffs
     * @param datas
     * @param integer
     */
    private static List<Integer> removeDate(int cycleTime, List<Integer> dateOffs,
                                            List<String> datas, Integer integer, List<Integer> indexs) {
        int s = datas.size() / cycleTime;
        if (s > 0) {
            for (int i = 0; i < s; i++) {
                indexs.add(i * cycleTime + integer - 1);
                int a = (s * cycleTime + integer) - 1;
                if ((i == (s - 1)) && a < datas.size()-1) {
                    indexs.add(a);
                }
            }

        } else {
            //只有一个周期的
            for (int i : dateOffs) {
                if (i < datas.size() + 1) {
                    indexs.add(i - 1);
                }
            }
        }
        return indexs;
    }


    /**
     * 获取当前时间所在周的周一和周日的日期时间
     *
     * @return
     */
    public static Map<String, String> getWeekDate(String format) {
        Map<String, String> map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat(format);

        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayWeek == 1) {
            dayWeek = 8;
        }
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);

        cal.add(Calendar.DATE, 4 + cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        String weekEnd = sdf.format(sundayDate);

        map.put("1", weekBegin);
        map.put("7", weekEnd);
        return map;
    }

    /**
     * 获取指定日期是星期几<br>
     */
    public static Integer dayForWeek(String dateString) {
        //注意参数的样式为yyyy-MM-dd,必须让参数样式与所需样式统一
        if (dateString == null) return 0;
        int dayForWeek = 0;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.setTime(sdf.parse(dateString));
            dayForWeek = 0;
            if (c.get(Calendar.DAY_OF_WEEK) == 1) {
                dayForWeek = 7;
            } else {
                dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dayForWeek;
    }

    /**
     * HH:mm转换分钟数
     *
     * @param str HH:mm
     * @return
     */
    public static long getDateMinutes(String str) {
        long minutes = 0;
        try {
            Date parse = new SimpleDateFormat(DateFormatUtil.HHmm).parse(str);
            minutes = parse.getHours() * 60 + parse.getMinutes();
        } catch (ParseException e) {
            log.info("传入参数格式有误：{}", str);
        }
        return minutes;

    }

    /**
     * 校验是否有覆盖
     *
     * @param begin
     * @param end
     * @param begin1
     * @param end1
     * @return
     */
    public static boolean checkCover(String begin, String end, String begin1, String end1) {
        boolean res = false;
        if (StringUtils.isBlank(begin) || StringUtils.isBlank(end) ||
                StringUtils.isBlank(begin1) || StringUtils.isBlank(end1)) return false;
        if (getDateMinutes(begin1) >= getDateMinutes(begin) && getDateMinutes(begin1) <= getDateMinutes(end)
                || getDateMinutes(end1) >= getDateMinutes(begin) && getDateMinutes(end1) <= getDateMinutes(end)
                || getDateMinutes(begin1) >= getDateMinutes(begin) && getDateMinutes(end1) <= getDateMinutes(end)
                || getDateMinutes(begin1) <= getDateMinutes(begin) && getDateMinutes(end1) >= getDateMinutes(end)) {
            res = true;
        }

        return res;
    }

    public static String date2String(Date date) {
        return date2String(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String date2String(Date date, String format) {
        String result = null;
        if (date != null) {
            DateFormat sdf = new SimpleDateFormat(format);
            result = sdf.format(date);
        }

        return result;
    }
    
    public static Date getYrMonthLastDay(Date d) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(2, 1);
        Date nextMonthFirstDay = getYrMonthFirstDay(calendar.getTime());
        calendar.setTime(nextMonthFirstDay);
        calendar.add(5, -1);
        return calendar.getTime();
    }

    public static Date getYrMonthFirstDay(Date d) {
        String yrMonth = date2String(d, "yyyyMM");
        String date = yrMonth + "01";
        return string2Date(date);
    }
    
    public static Date string2Date(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        } else {
            dateStr = dateStr.trim();
            Date date = null;
            switch(dateStr.length()) {
                case 8:
                    date = string2Date(dateStr, "yyyyMMdd");
                    break;
                case 9:
                case 12:
                case 13:
                case 15:
                case 16:
                case 18:
                case 20:
                case 22:
                default:
                    throw new IllegalArgumentException(dateStr + "不支持的时间格式");
                case 10:
                    date = string2Date(dateStr, dateStr.indexOf("/") == -1 ? "yyyy-MM-dd" : "yyyy/MM/dd");
                    break;
                case 11:
                    date = string2Date(dateStr, "yyyy年MM月dd日");
                    break;
                case 14:
                    date = string2Date(dateStr, "yyyyMMddHHmmss");
                    break;
                case 17:
                    date = string2Date(dateStr, "yyyyMMddHHmmssSSS");
                    break;
                case 19:
                    date = string2Date(dateStr, dateStr.indexOf("/") == -1 ? "yyyy-MM-dd HH:mm:ss" : "yyyy/MM/dd HH:mm:ss");
                    break;
                case 21:
                    date = string2Date(dateStr, "yyyy年MM月dd日 HH时mm分ss秒");
                    break;
                case 23:
                    date = string2Date(dateStr, dateStr.indexOf("/") == -1 ? "yyyy-MM-dd HH:mm:ss.SSS" : "yyyy/MM/dd HH:mm:ss.SSS");
            }

            return date;
        }
    }

    public static Date string2Date(String date, String format) {
        if (StringUtils.isEmpty(format)) {
            throw new IllegalArgumentException("the date format string is null!");
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat(format);

            try {
                return sdf.parse(date.trim());
            } catch (ParseException var4) {
                throw new IllegalArgumentException("the date string " + date + " is not matching format: " + format, var4);
            }
        }
    }

}
